<?
/*! \brief Base representation of an OpenBT node
 * 
 */
class Node
{
	public $_db, $_regtype, $_type, $_table, $_addr, $_refresh;
	
	public function __construct($addr=null)
	{
		$this->_db = Zend_Registry::get('db');
		$this->_addr = $addr;
		$this->_refresh = 10; //seconds
	}
	
	public function register($array)
	{
		if($this->_type)
			$this->localRegister($array);
		else
			$this->remoteRegister($array, $this->_addr);
	}
		
	public function localRegister($array)
	{	
		//Check for null values
		if($array['ip'] == null || $array['username'] == null || 
			$array['password'] == null)
		{
			Logger::file()->err('Cannot register new '.$this->_regtype.
				': input array is missing some values.');
			return -1;
		}
		
		$authorized = Auth::authenticate($array['username'], 
			$array['password']);
		
		//Only if login was successful...
		if($authorized)
		{			
			//Only if node isn't already registered...
			if(! $this->isRegistered($array['ip']))
			{
				try
				{
					$this->_db->insert($this->_table, 
						array('addr' => $array['ip']));
				}
				catch(Exception $e)
				{
					Logger::file()->err('Failed to register new '.
						$this->_regtype.': '.$array['ip']);
					$db->rollback;
				}
			}
		}
	}
	
	public function remoteRegister($array, $addr)
	{
		$client = new Zend_Http_Client($addr."/Service/register");
		$client->setParameterGet('type', $this->_regtype);
		$client->setParameterGet($array);
		
		$response = $client->request();
			
		if($response->getStatus() == 200)
			return false;
	}
	
	public function isRegistered($addr=null)
	{	
		$sql = 'SELECT * FROM `'.$this->_table.'` WHERE `addr`= ?';
		$this->_db->setFetchMode(Zend_Db::FETCH_OBJ);
		$result = $this->_db->fetchAll($sql, $addr);
		
		if(sizeof($result) > 0)
			return true;
		else
			return false;
	}
	
	public function getAddressList()
	{
		if($this->_type)
		{
			$sql = 'SELECT `addr` FROM `'.$this->_table.
				'` WHERE NOW() - `updated` > '.$this->_refresh;
			$this->_db->setFetchMode(Zend_Db::FETCH_OBJ);
			$result = $this->_db->fetchAll($sql,2);
			
			if(sizeof($result) > 0)
				return $result;
		}
		return false;
	}
	
	public function getNodeLeastLoad()
	{
		if($this->_type)
		{
			$sql = 'SELECT `addr` FROM `'.$this->_table.
				'` WHERE `load` != -1 ORDER BY `load` ASC';
			$this->_db->setFetchMode(Zend_Db::FETCH_OBJ);
			$result = $this->_db->fetchAll($sql,2);
			
			if(sizeof($result) > 0)
				return $result[0]->addr;
		}
		return null;
	}
	
	public function getRemoteLoad()
	{
		$client = new Zend_Http_Client($this->_addr."/Service/reportload");
		$client->setParameterGet('type', get_class($this));
		
		$response = $client->request();
			
		if($response->getStatus() != 200)
			return false;
			
		return $response->getBody();
	}
	
	public function setLoad($addr, $load)
	{
		if($this->_type)
		{
			//create data array for update
			$data = array(	'load' => $load,
							'updated' => NULL);
					
			//Get the master's id
			$sql = 'SELECT `id` FROM `'.$this->_table.'` WHERE `addr`= ?';
			$this->_db->setFetchMode(Zend_Db::FETCH_OBJ);
			$result = $this->_db->fetchAll($sql, $addr);
				
			if(sizeof($result) > 0)
			{
				try
				{
					$this->_db->update($this->_table, $data, 'id = '.
						$result[0]->id);
				}
				catch(Exception $e)
				{
					Logger::file()->info(HOST_NAME.' failed to set load for '.
						$addr);
					$this->_db->rollback();
					return false;
				}
			}
			return true;
		}
	}
}